﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

// std headers
#include <string>
#include <map>
#include <memory>

// qt headers
#include <QNetworkReply>
#include <QString>

// custom headers
#include "GcsService.h"
#include "LegendsResponseHandler.h"
#include "PagedLegendsResponseHandler.h"
#include "ProjectComponentExistingCheckResponseHandler.h"
#include "ProjectComponentExistingCheck.h"
#include "GbmpNew.h"


namespace gmepgcs
{
    template<typename TResult>
    class ResponseHandlerFactory
    {
    private:
        explicit ResponseHandlerFactory() = delete;
        ResponseHandlerFactory(const ResponseHandlerFactory &) = default;
        ResponseHandlerFactory &operator=(const ResponseHandlerFactory &) = default;
        virtual ~ResponseHandlerFactory() = default;

    public:
        static TResult Handle(QNetworkReply *pReply, std::wstring & errorMessage);
        static IResponseHandler<TResult> *GetHandler(const std::wstring &typeName);

    private:
        static std::map<std::wstring, void*> m_mpHandlers;
    };


    template<typename TResult>
    inline TResult ResponseHandlerFactory<TResult>::Handle(QNetworkReply * pReply, std::wstring & errorMessage)
    {
        IResponseHandler<TResult> *pResponseHandler = ResponseHandlerFactory<TResult>::GetHandler(QString(typeid(TResult).name()).toStdWString());

        if (!pResponseHandler)
        {
            errorMessage = L"ResponseHandler not found.";
            return TResult();
        }

        TResult result = pResponseHandler->Handle(pReply, errorMessage);
        return result;
    }

    template<typename TResult>
    inline IResponseHandler<TResult> *ResponseHandlerFactory<TResult>::GetHandler(const std::wstring &typeName)
    {
        auto found = ResponseHandlerFactory<TResult>::m_mpHandlers.find(typeName);
        if (found != ResponseHandlerFactory<TResult>::m_mpHandlers.end())
        {
            return static_cast<IResponseHandler<TResult> *>((*found).second);
        }

        void * pHandler = nullptr;
       /* if (SimpleDataResponseHandler<TResult>::IsDefined())
        {
            pHandler = NEW_AS_QT(SimpleDataResponseHandler<TResult>);
        }*/
        //else if (typeName == QString(typeid(std::shared_ptr<IProjectComponent>).name()).toStdWString())
        //{
        //    pHandler = NEW_AS_QT(ProjectComponentResponseHandler);
        //}
        //else if (typeName == QString(typeid(std::shared_ptr<IDetailedProjectComponent>).name()).toStdWString())
        //{
        //    pHandler = NEW_AS_QT(DetailedProjectComponentResponseHandler);
        //}
        /*else*/ if (typeName == QString(typeid(std::vector<std::shared_ptr<ILegend>>).name()).toStdWString())
        {
            pHandler = NEW_AS_QT(LegendsResponseHandler);
        }
        else if (typeName == QString(typeid(IPagedData<std::vector<std::shared_ptr<ILegend>>>).name()).toStdWString())
        {
            pHandler = NEW_AS_QT(PagedLegendsResponseHandler);
        }
        //else if (typeName == QString(typeid(std::shared_ptr<ICategoryProperty>).name()).toStdWString())
        //{
        //    pHandler = NEW_AS_QT(CategoryPropertyResponseHandler); // 分类下的属性- 
        //}
        //else if (typeName == QString(typeid(std::vector<std::shared_ptr<ICategory>>).name()).toStdWString())
        //{
        //    pHandler = NEW_AS_QT(CategoriesResponseHandler);
        //}
        else if (typeName == QString(typeid(std::shared_ptr<ProjectComponentExistingCheck>).name()).toStdWString())
        {
            pHandler = NEW_AS_QT(ProjectComponentExistingCheckResponseHandler); // 是否存在
        }

        if (nullptr != pHandler)
        {
            ResponseHandlerFactory<TResult>::m_mpHandlers[typeName] = pHandler;
        }
        
        return static_cast<IResponseHandler<TResult> *>(pHandler);
    }

    template<typename TResult>
    std::map<std::wstring, void*> ResponseHandlerFactory<TResult>::m_mpHandlers = std::map<std::wstring, void*>();

}